package be.sc.classicnetwork.controller;

import java.util.Collection;
import java.util.HashSet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.ModelAndView;

import be.sc.classicnetwork.model.Car;
import be.sc.classicnetwork.model.Image;
import be.sc.classicnetwork.model.Option;
import be.sc.classicnetwork.service.impl.EmailCarNotficationTask;
import be.sc.classicnetwork.util.PropertiesUtils;

/**
 * Form Controller for cars.
 */
public class CarFormController extends AbstractFormController {

    private String rootUrl;

    /**
     * @see org.springframework.web.servlet.mvc.AbstractFormController#formBackingObject(javax.servlet.http.HttpServletRequest)
     */
    @Override
    protected Object formBackingObject(HttpServletRequest request) throws Exception {
	String id = ServletRequestUtils.getStringParameter(request, "id", null);
	return (StringUtils.isEmpty(id)) ? new Car() : getServiceLocator().getCarService().findByIdFull(id);
    }

    /**
     * @see be.sc.classicnetwork.controller.AbstractFormController#initBinder(javax.servlet.http.HttpServletRequest,
     *      org.springframework.web.bind.ServletRequestDataBinder)
     */
    @Override
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
	super.initBinder(request, binder);

	// for the one-to-many form (images)
	Car car = (Car) binder.getTarget();
	int addressesMaxIndex = getMaxIndex(request, "h_images");
	if (addressesMaxIndex > -1) {
	    for (int i = 0; i <= addressesMaxIndex; i++) {
		car.getUploadImages().add(new Image());
	    }
	}
    }

    @Override
    protected void onBind(HttpServletRequest request, Object command) throws Exception {
	super.onBind(request, command);
    }

    /**
     * @see org.springframework.web.servlet.mvc.BaseCommandController#onBindAndValidate(javax.servlet.http.HttpServletRequest,
     *      java.lang.Object, org.springframework.validation.BindException)
     */
    @Override
    protected void onBindAndValidate(HttpServletRequest request, Object command, BindException errors) throws Exception {
	Car car = (Car) command;

	// removes the empty images
	car.removeEmptyUploadImages();

	// add the uploaded file if any
	car.getImages().addAll(car.getUploadImages());
    }

    /**
     * @see org.springframework.web.servlet.mvc.SimpleFormController#onSubmit(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse, java.lang.Object,
     *      org.springframework.validation.BindException)
     */
    @Override
    protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command,
	    BindException errors) throws Exception {
	Car car = (Car) command;
	String action = ServletRequestUtils.getRequiredStringParameter(request, "action");

	return (action.equals("email")) ? email(request, response, car, errors) : save(request, response, car, errors);
    }

    /**
     * save.
     */
    private ModelAndView save(HttpServletRequest request, HttpServletResponse response, Car car, BindException errors)
	    throws Exception {
	// get images to delete
	String[] i2delete = ServletRequestUtils.getStringParameters(request, "2delete");
	Image[] images2delete = new Image[i2delete.length];
	for (int i = 0; i < i2delete.length; i++) {
	    images2delete[i] = new Image(i2delete[i]);
	}

	// get selected options
	String[] opts = ServletRequestUtils.getStringParameters(request, "opts");
	Collection<Option> options = new HashSet<Option>();
	for (int i = 0; i < opts.length; i++) {
	    options.add(new Option(opts[i]));
	}

	// save or update
	getServiceLocator().getCarService().saveOrUpdate(car, images2delete, options);

	// show confirmation message
	showMessage(request, "Car successfully saved");
	return showForm(request, errors, getFormView());
    }

    /**
     * email.
     */
    private ModelAndView email(HttpServletRequest request, HttpServletResponse response, Car car, BindException errors)
	    throws Exception {
	// get car from DB
	car = getServiceLocator().getCarService().findById(car.getId());

	// get some application properties
	String from = PropertiesUtils.MAIL_FROM;
	String fromPersonal = PropertiesUtils.MAIL_FROM_PERSONAL;
	String subjectPrefix = PropertiesUtils.MAIL_SUBJECT_PREFIX;

	// start another thread to send the email
	getTaskExecutor().execute(
		new EmailCarNotficationTask(getServiceLocator().getCarService(), getServiceLocator().getMailService(),
			car, from, fromPersonal, rootUrl, subjectPrefix + " Alert"));

	// show confirmation message
	// show confirmation message
	return new ModelAndView("info", "text", "Notification sent");
    }

    public void setRootUrl(String rootUrl) {
	this.rootUrl = rootUrl;
    }

}
